package com.common.ajax.server;

import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.ServletException;
import javax.xml.namespace.QName;

import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;
import org.apache.log4j.Logger;
import org.dom4j.Document;

import com.caits.lbs.framework.Constants;
import com.caits.lbs.framework.log.CommonLogFactory;
import com.caits.lbs.framework.utils.XmlUtil;

/**
 * <p>
 * XMLPost
 * </p>
 * <p>
 * 请求的SOAP调用处理类
 * </p>
 * 
 * @author 周华彬(zhouhuabin@ctfo.com, zhou_hua_bin@163.com)
 * @version 0.0.0
 *          <table style="border:1px solid gray;">
 *          <tr>
 *          <th width="100px">版本号</th>
 *          <th width="100px">动作</th>
 *          <th width="100px">修改人</th>
 *          <th width="100px">修改时间</th>
 *          </tr>
 *          <!-- 以 Table 方式书写修改历史 -->
 *          <tr>
 *          <td>0.0.0</td>
 *          <td>创建类</td>
 *          <td>zhb</td>
 *          <td>2011-4-2 下午03:04:31</td>
 *          </tr>
 *          <tr>
 *          <td>XXX</td>
 *          <td>XXX</td>
 *          <td>XXX</td>
 *          <td>XXX</td>
 *          </tr>
 *          </table>
 */
public class RequestSOAPParser implements IRequest {
	/** 序列 */
	@SuppressWarnings("unused")
	private static final long serialVersionUID = 1L;

	/** 远程调用对象的key */
	private static final String RPCClient_KEY = "rpcClient";

	/** log writer */
	protected static Logger log = CommonLogFactory.getLog();

	
	/** 方法传入的参数类型 */
	protected Class<?>[] classes = new Class[] { String.class, String.class ,Integer.class};

	/** 方法传入的参数 */
	protected Object[] opAddEntryArgs = new Object[] { "123", "<a>123</a>",0 };

	/** webservice服务调用实例 */
	protected RPCServiceClient serviceClient = null;

	protected QName opAddEntry = null;

	/** 系统常量类 */
	protected Constants constant;

	/** 远程会话缓存 */
	protected static Map<String, RPCServiceClient> rpcMap = new ConcurrentHashMap<String, RPCServiceClient>();

	// Initialize global variables
	public void init() throws ServletException {
		opAddEntry = new QName(constant.getNameSpace(),
				constant.getMethodName());
		log.info("处理器运行在webservice模式，endPoint:" + constant.getEndpoint());

	}

	/**
	 * 获取远程webservice连接对象
	 * 
	 * @param request
	 * @return
	 */
	private RPCServiceClient getRPCServiceClient(SessionMap ssMap) {
		RPCServiceClient local_serviceClient = null;
		
		if (ssMap.containsAtribute(RPCClient_KEY)) {
			local_serviceClient = (RPCServiceClient) ssMap.getAttribute(RPCClient_KEY);
		} else {
			try {
				local_serviceClient = getServiceClient();
				Options options = local_serviceClient.getOptions();
				options.setManageSession(true);
				EndpointReference targetEPR = new EndpointReference(
						constant.getEndpoint());
				options.setTo(targetEPR);
				options.setAction("urn:" + constant.getMethodName());
				opAddEntry = new QName(constant.getNameSpace(),
						constant.getMethodName());
				log.info("创建webservice客户端成功，endPoint:" + constant.getEndpoint());
				ssMap.setAttribute(RPCClient_KEY, local_serviceClient);
			} catch (Exception e) {
				log.error("创建webservice客户端失败，endPoint:"
						+ constant.getEndpoint(),e);
			}

		}
		return local_serviceClient;
	}

	/* 调用远程soap的实现，参数类型是document
	 * (non-Javadoc)
	 * @see com.common.ajax.server.IRequest#request(org.jdom.Document, com.common.ajax.server.SessionMap)
	 */
	@Override
	public Document request(Document doc, SessionMap session)
			throws SecurityException, NoSuchMethodException,
			IllegalAccessException, InvocationTargetException, SQLException,
			RuntimeException {
		int result = IRequest.ERROR_SUCCEED;
		String className = "no-parse-server";
		Object[] return_obj = null;
		Document ret = null;
		try {
			synchronized (opAddEntryArgs) {
				opAddEntryArgs[1] = doc;
				RPCServiceClient client= getRPCServiceClient(session);
				return_obj = client.invokeBlocking(opAddEntry,
						opAddEntryArgs, classes);
			}
			ret = (Document) return_obj[0];
			log.debug("call webservice result:" + ret.toString().length());
		} catch (AxisFault ex1) {
			log.error(IRequest.ERROR_AXISFAULT_DESC + ex1.getLocalizedMessage(),ex1);
			result = IRequest.ERROR_AXISFAULT_ACCESS;
			return RequestParser.createError(className, result,
					IRequest.ERROR_AXISFAULT_DESC);
			//
		} catch (Exception ex1) {
			result = IRequest.ERROR_INSTANTIATION;
			log.error(IRequest.ERROR_INSTANTIATION_DESC + ex1.getLocalizedMessage(),ex1);
			return RequestParser.createError(className, result,
					IRequest.ERROR_INSTANTIATION_DESC);
		}
		return ret;
	}

	/* 调用远程soap的实现，参数类型是xml字符串
	 * (non-Javadoc)
	 * @see com.common.ajax.server.IRequest#request(java.lang.String, com.common.ajax.server.SessionMap)
	 */
	@Override
	public String request(String xmlStr, SessionMap session)
			throws SecurityException, NoSuchMethodException,
			IllegalAccessException, InvocationTargetException, SQLException,
			RuntimeException {
		int result = IRequest.ERROR_SUCCEED;
		String className = "no-parse-server";
		Object[] return_obj = null;
		String ret = null;
		try {
			synchronized (opAddEntryArgs) {
				opAddEntryArgs[1] = xmlStr;
				RPCServiceClient client= getRPCServiceClient(session);
				return_obj = client.invokeBlocking(opAddEntry,
						opAddEntryArgs, classes);
			}
			ret = (String) return_obj[0];
			log.debug("call webservice result:" + ret.substring(0,Math.min(Constants.max_log_output,ret.length())));
		} catch (AxisFault ex1) {
			result = IRequest.ERROR_AXISFAULT_ACCESS;
			log.error(IRequest.ERROR_AXISFAULT_DESC + ex1.getLocalizedMessage(),ex1);
			return XmlUtil.documentToString(RequestParser.createError(className, result,
					IRequest.ERROR_AXISFAULT_DESC));
			//
		} catch (Exception ex1) {
			result = IRequest.ERROR_INSTANTIATION;
			log.error(IRequest.ERROR_INSTANTIATION_DESC + ex1.getLocalizedMessage(),ex1);
			return XmlUtil.documentToString(RequestParser.createError(className, result,
					IRequest.ERROR_INSTANTIATION_DESC));
		}
		return ret;
	}

	/**
	 * 获取变量constant的值
	 * @return the constant 数据类型 : Constants
	 */
	public Constants getConstant() {
		return constant;
	}

	/**
	 * 设置变量 constant 的值，数据类型：Constants
	 * @param constant the constant to set
	 */
	public void setConstant(Constants constant) {
		this.constant = constant;
	}

	/**
	 * 获取变量serviceClient的值
	 * @return the serviceClient 数据类型 : RPCServiceClient
	 * @throws AxisFault 
	 */
	public RPCServiceClient getServiceClient() throws AxisFault {
		return new RPCServiceClient();
//		return serviceClient;
	}

	/**
	 * 设置变量 serviceClient 的值，数据类型：RPCServiceClient
	 * @param serviceClient the serviceClient to set
	 */
	public void setServiceClient(RPCServiceClient serviceClient) {
		this.serviceClient = serviceClient;
	}

}
